package Array;

import java.util.HashSet;
import java.util.Set;

/**
 * 有效的数独
 *  请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ，验证已经填入的数字是否有效即可。
 * 数字 1-9 在每一行只能出现一次。
 * 数字 1-9 在每一列只能出现一次。
 * 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。（请参考示例图）
 * 注意：
 * 一个有效的数独（部分已被填充）不一定是可解的。
 * 只需要根据以上规则，验证已经填入的数字是否有效即可。
 * 空白格用 '.' 表示。
 *
 *
 * 思路：此题是条件限制题目已经明确给出，每一行、每一列，3*3范围都不允许出现相同的数字。
    判断重复的数字出现，我们可以直接使用Set去判断
    对题目中的条件进行转换：
        1：每一行都不允许出现相同，即 row+i+number 不允许重复
        2：每一列都不允许出现相同，即 col+i+number 不允许重复
        3：3*3范围内的数字不允许出现重复， 即box+i/3+j/3+number 不允许重复
    如果number为空格，跳过
    所以，我们通过Set的特性，添加3个条件，判断是否重复即可
   翻译为代码。
 */
public class SudokuQuestion {
    public boolean isValidSudoku(char[][] board) {
        // 检查board是否为null和是否为9x9
        if (board == null || board.length != 9 || board[0].length != 9) {
            throw new IllegalArgumentException("Invalid Sudoku board: board must be non-null and 9x9.");
        }

        // 因为存在空格，所以我们创建三个Set分别判断行，列，3*3区域的数字
        Set<String> rows = new HashSet<>(); // 用于存储每行的数字组合
        Set<String> columns = new HashSet<>(); // 用于存储每列的数字组合
        Set<String> boxes = new HashSet<>(); // 用于存储每个3x3盒子的数字组合


        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j <board[i].length ; j++) {
                if(board[i][j] == '.'){
                    continue;
                }
                String number = String.valueOf(board[i][j]);
                if(!rows.add(i+number)){
                    return false;
                }
                if(!columns.add(j+number)){
                    return false;
                }
                // 检查3+3
                int boxRow = i / 3;
                int boxCol = j / 3;
                if(!boxes.add(boxRow+""+boxCol+number)){
                    return false;
                }
            }
        }
        return true;
    }
}
